using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Interop;
using System.Windows.Media;
using GurLoader.GlobalHotkey;
using GurLoader.Preferences;
using GurLoader.Service.HotKeyManager;
using GurLoader.Service.ScreenshotUpload;
using GurLoader.View;

namespace GurLoader.Service.HotKeyManager
{
    public class HotKeyManagerService : IHotKeyManagerService
    {
        private GurLoaderPreferences appPreferences;
        private IScreenshotUploadService ScreenshotUploadService { get; set; }
        private IWindow HotkeyWindow { get; set; }
        private IHotKeyHost HotkeyHost { get; set; }
        private IDispatcher Dispatcher { get; set; }

        private bool disposed;

        public HotKeyManagerService(
            GurLoaderPreferences appPreferences, 
            IDispatcher dispatcher,
            IScreenshotUploadService screenshotUploadService, 
            IViewBuilder viewBuilder,
            IHwndSourceFactory hwndSourceFactory,
            IWindowsHotkeyProvider windowsHotkeyProvider)
        {
            if (appPreferences == null)
                throw new ArgumentNullException("appPreferences");

            if (dispatcher == null)
                throw new ArgumentNullException("dispatcher");

            if (screenshotUploadService == null)
                throw new ArgumentNullException("screenshotUploadService");

            if (viewBuilder == null)
                throw new ArgumentNullException("viewBuilder");

            if (hwndSourceFactory == null)
                throw new ArgumentNullException("hwndSourceFactory");

            if (windowsHotkeyProvider == null)
                throw new ArgumentNullException("windowsHotkeyProvider");

            AppPreferences = appPreferences;
            

            ScreenshotUploadService = screenshotUploadService;
            Dispatcher = dispatcher;

            HotkeyWindow = viewBuilder.CreateHotkeyWindow(false);
            HotkeyHost = new HotKeyHost(
                hwndSourceFactory.GetHwndSource( HotkeyWindow ),
                windowsHotkeyProvider);
        }

        public HotKeyManagerService(GurLoaderPreferences appPreferences, IDispatcher dispatcher,
            IScreenshotUploadService screenshotUploadService, IHotKeyHost hotkeyHost)
        {
            if ( appPreferences == null )
                throw new ArgumentNullException("appPreferences");

            if ( dispatcher == null ) 
                throw new ArgumentNullException("dispatcher");

            if ( screenshotUploadService == null )
                throw new ArgumentNullException("screenshotUploadService");

            if ( hotkeyHost == null )
                throw new ArgumentNullException("hotkeyHost");

            AppPreferences = appPreferences;

            ScreenshotUploadService = screenshotUploadService;
            HotkeyHost = hotkeyHost;
            Dispatcher = dispatcher;
        }

        public GurLoaderPreferences AppPreferences
        {
            get { return appPreferences; }
            set
            {
                if (appPreferences != null)
                    appPreferences.PreferencesSaved -= OnPreferencesSaved;

                appPreferences = value;

                if (appPreferences != null)
                    appPreferences.PreferencesSaved += OnPreferencesSaved;
            }
        }

        public void CreateBindings()
        {
            if (AppPreferences.FullScreenCaptureEnabled)
            {

                HotkeyHost.AddHotKey(new HotKey(
                    AppPreferences.FullScreenCaptureKey, AppPreferences.FullScreenCaptureModifierKeys, 
                    true,
                    () => ScreenshotUploadService.UploadFullScreen()));
            }

            if (AppPreferences.AreaScreenCaptureEnabled)
            {
                HotkeyHost.AddHotKey(new HotKey(
                    AppPreferences.AreaScreenCaptureKey, AppPreferences.AreaScreenCaptureModifierKeys,
                    true,
                    () => ScreenshotUploadService.UploadScreenArea(Dispatcher, true)));
            }
        }

        public void RemoveBindings()
        {
            List<HotKey> hotKeys = HotkeyHost.HotKeys.ToList();
            foreach (var hotKey in hotKeys)
            {
                HotkeyHost.RemoveHotKey(hotKey);
            }
        }

        public IEnumerable<HotKey> Bindings
        {
            get { return HotkeyHost.HotKeys; }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool isDisposing)
        {
            if (disposed)
                return;

            if (isDisposing)
            {
                var host = HotkeyHost as IDisposable;
                if (host != null)
                {

                    if (HotkeyHost != null)
                        host.Dispose();

                    if (HotkeyWindow != null)
                        HotkeyWindow.CloseWindow();
                }
            }

            disposed = true;
        }

        protected void OnPreferencesSaved(object sender, EventArgs e)
        {
            RemoveBindings();
            CreateBindings();
        }
    }
}